package com.app.util.string;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 字符串工具类
 * 
 * @author YM
 */
public class StringUtil {

	/**
	 * 截取选定字符<br>
	 * 调用: getSection("这个方法用来|截取指定|字符串!","|","|")返回结果是: "截取指定"
	 * 
	 * @param string
	 *            字符串
	 * @param start
	 *            开始字符串
	 * @param end 
	 *            结尾字符串
	 * @return
	 */
	public static String getSection(String string, String start, String end) {
		try {
			if (!allNotEmpty(new String[] { string, start, end })) {
				return null;
			}
			int startPoint = string.indexOf(start);
			if (startPoint == -1)
				return null;
			startPoint += start.length();
			int endPoint = string.indexOf(end, startPoint);
			if (endPoint == -1 || endPoint < startPoint)
				return null;
			return string.substring(startPoint, endPoint);
		} catch (Exception ex) {
			return null;
		}
	}

	/**
	 * 截取选定字符（最大长度）<br>
	 * 调用: getSection("这个方法用来|截取指定|字符|串!","|","|")返回结果是: "截取指定|字符"
	 * 
	 * @param string
	 *            字符串
	 * @param start
	 *            开始字符串
	 * @param end
	 *            结尾字符串
	 * @return
	 */
	public static String getSectionOuter(String string, String start, String end) {
		try {
			if (!allNotEmpty(new String[] { string, start, end })) {
				return null;
			}
			int startPoint = string.indexOf(start);
			if (startPoint == -1)
				return null;
			startPoint += start.length();
			int endPoint = string.lastIndexOf(end);
			if (endPoint == -1)
				return null;
			return string.substring(startPoint, endPoint);
		} catch (Exception ex) {
			return null;
		}
	}

	/**
	 * 截取选定字符<br>
	 * 调用: getLeft("这个方法用来|截取指定|字符串!","|")返回结果是: "这个方法用来"
	 * 
	 * @param string
	 * @param point
	 * @return
	 */
	public static String getLeft(String string, String point) {
		int start = string.indexOf(point);
		if (start == -1) {
			return null;
		}
		return string.substring(0, start);
	}

	/**
	 * 截取选定字符<br>
	 * 调用: getLeftOuter("这个方法用来|截取指定|字符串!","|")返回结果是: "这个方法用来|截取指定"
	 * 
	 * @param string
	 * @param point
	 * @return
	 */
	public static String getLeftOuter(String string, String point) {
		if (StringUtil.isEmpty(point)) {
			return string;
		}
		int start = string.lastIndexOf(point);
		if (start == -1) {
			return null;
		}
		return string.substring(0, start);
	}

	/**
	 * 截取选定字符<br>
	 * 调用: getRight("这个方法用来|截取指定|字符串!","|")返回结果是: "字符串!"
	 * 
	 * @param string
	 * @param point
	 * @return
	 */
	public static String getRight(String string, String point) {
		int start = string.lastIndexOf(point);
		if (start == -1) {
			return null;
		}
		start += point.length();
		return string.substring(start);
	}

	/**
	 * 截取选定字符<br>
	 * 调用: getRightOuter("这个方法用来|截取指定|字符串!","|")返回结果是: "截取指定|字符串!"
	 * 
	 * @param string
	 * @param point
	 * @return
	 */
	public static String getRightOuter(String string, String point) {
		if (StringUtil.isEmpty(point)) {
			return string;
		}
		int start = string.indexOf(point);
		if (start == -1) {
			return null;
		}
		start += point.length();
		return string.substring(start);
	}

	/**
	 * 是否为null或""
	 * 
	 * @param string
	 * @return
	 */
	public static boolean isEmpty(String string) {
		if (null == string)
			return true;
		return string.equals("");
	}

	/**
	 * 是否为 null 或 空格字符
	 * 
	 * @param string
	 * @return
	 */
	public static boolean isTrimEmpty(String string) {
		return toString(string).trim().equals("");
	}

	/**
	 * 判断两个字符串是否相同
	 * 
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static boolean equals(String s1, String s2) {
		if (s1 == s2) {
			return true;
		} else if (s1 == null) {
			return false;
		} else if (s2 == null) {
			return false;
		}
		return s1.equals(s2);
	}

	/**
	 * 判断两个字符串是否相同（不区分大小写）
	 * 
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static boolean equalsIgnoreCase(String s1, String s2) {
		if (s1 == s2) {
			return true;
		} else if (s1 == null) {
			return false;
		} else if (s2 == null) {
			return false;
		}
		return s1.equalsIgnoreCase(s2);
	}

	/**
	 * 调用obj的toString方法，如果异常则返回""
	 * 
	 * @param o
	 * @return
	 */
	public static String toString(Object o) {
		if (null == o)
			return "";
		try {
			return o.toString();
		} catch (Exception e) {
			return "";
		}
	}

	private static Map<String, String> Smap = new HashMap<String, String>();
	static {
		Smap.put("\\n", "\n");
		Smap.put("\\t", "\t");
		Smap.put("\\b", "\b");
		Smap.put("\\f", "\f");
		Smap.put("\\r", "\r");

		Smap.put("\\\\", "\\");
		Smap.put("\\'", "\'");
		Smap.put("\\\"", "\"");

		Smap.put("\\0", "\0");
	}

	/**
	 * 将实际字符串转换为规范的JAVA代码字符串<br />
	 * 其中包括的转义对象有：<br />
	 * <li>("\\n", "\n");</li>
	 * <li>("\\t", "\t");</li>
	 * <li>("\\b", "\b");</li>
	 * <li>("\\f", "\f");</li>
	 * <li>("\\r", "\r");</li>
	 * <li>("\\\\", "\\");</li>
	 * <li>("\\'", "\'");</li>
	 * <li>("\\\"", "\"");</li>
	 * <li>("\\0", "\0");</li>
	 * 
	 * @param s
	 *            对象 null 返回 null
	 * @return
	 */
	public static String toCodeString(String s) {
		if (null == s)
			return null;
		try {
			StringBuffer sb = new StringBuffer(s);
			for (Entry<String, String> ent : Smap.entrySet()) {
				StringBufferUtil.replaceStrAllNotBack(sb, ent.getValue(), ent.getKey());
			}
			sb.append("\"");
			sb.insert(0, "\"");
			return sb.toString();
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 将对象转换成字符串后，执行toCodeString(String s) ;
	 * 
	 * @param o
	 * @return
	 */
	public static String toCodeString(Object o) {
		if (null == o)
			return null;
		return toCodeString(o.toString());
	}

	/**
	 * 将规范的JAVA代码字符串转为实际字符串<br />
	 * 与toCodeString(Object o)正好相反
	 * 
	 * @param o
	 * @return
	 */
	public static String fromCodeString(String s) {
		if (null == s)
			return null;
		if (s.equals("null"))
			return null;
		try {
			StringBuffer sb = new StringBuffer(s);
			for (Entry<String, String> ent : Smap.entrySet()) {
				StringBufferUtil.replaceStrAllNotBack(sb, ent.getKey(), ent.getValue());
			}
			return StringUtil.getSectionOuter(sb.toString(), "\"", "\"");
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 重复字符串
	 * 
	 * @param s
	 * @param count
	 * @return
	 */
	public static String repeat(String s, int count) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < count; i++) {
			sb.append(s);
		}
		return sb.toString();
	}

	/**
	 * 用字符串填充数组
	 * 
	 * @param ss
	 *            等填充的数组
	 * @param s
	 *            填充用的字符串
	 */
	public static String[] fillArray(String[] ss, String s) {
		for (int i = 0; i < ss.length; i++) {
			ss[i] = s;
		}
		return ss;
	}

	/**
	 * 转换成大写
	 * 
	 * @param str
	 * @return 非NULL
	 */
	public static String toUpperCase(String str) {
		return toString(str).toUpperCase();
	}

	/**
	 * 转换成小写
	 * 
	 * @param str
	 * @return 非NULL
	 */
	public static String toLowerCase(String str) {
		return toString(str).toLowerCase();
	}

	/**
	 * 数组连接组装成字符串
	 * 
	 * @param objs
	 *            对象数组
	 * @return
	 */
	public static String linkString(Object[] objs) {
		return linkString(objs, "");
	}

	/**
	 * 数组连接组装成字符串
	 * 
	 * @param objs
	 *            对象数组
	 * @param splitStr
	 *            分隔字符串
	 * @return
	 */
	public static String linkString(Object[] objs, String splitStr) {
		return linkString(objs, splitStr, Object2StringHandler.SimpleHandler);
	}

	/**
	 * 数组连接组装成字符串
	 * 
	 * @param objs
	 * @param splitStr
	 * @param handler
	 *            Object转字符串处理器
	 * @return
	 */
	public static String linkString(Object[] objs, String splitStr, Object2StringHandler handler) {
		if (null == objs) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		boolean first = true;
		for (Object o : objs) {
			if (first) {
				first = false;
			} else {
				sb.append(splitStr);
			}
			sb.append(handler.toString(o));
		}
		return sb.toString();
	}

	/**
	 * 集合连接组装成字符串
	 * 
	 * @param objs
	 *            对象集合
	 * @return
	 */
	public static String linkString(Collection<?> objs) {
		return linkString(objs, "");
	}

	/**
	 * 集合连接组装成字符串
	 * 
	 * @param objs
	 *            对象集合
	 * @param splitStr
	 *            分隔字符串
	 * @return
	 */
	public static String linkString(Collection<?> objs, String splitStr) {
		return linkString(objs, splitStr, Object2StringHandler.SimpleHandler);
	}

	/**
	 * 集合连接组装成字符串
	 * 
	 * @param objs
	 * @param splitStr
	 * @param handler
	 *            Object转字符串处理器
	 * @return
	 */
	public static String linkString(Collection<?> objs, String splitStr, Object2StringHandler handler) {
		if (null == objs) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		boolean first = true;
		for (Object s : objs) {
			if (first) {
				first = false;
			} else {
				sb.append(splitStr);
			}
			sb.append(handler.toString(s));
		}
		return sb.toString();
	}

	/**
	 * 数组连接组装成字符串
	 * 
	 * @param chars
	 *            字符数组
	 * @param splitStr
	 *            分隔字符串
	 * @return
	 */
	public static String linkString(char[] chars, String splitStr) {
		if (null == chars) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		boolean first = true;
		for (Object s : chars) {
			if (first) {
				first = false;
			} else {
				sb.append(splitStr);
			}
			sb.append(s);
		}
		return sb.toString();
	}

	/**
	 * Map拼接字符串
	 * 
	 * @param map
	 * @return
	 */
	public static String linkString(Map<?, ?> map) {
		if (null == map) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		sb.append(map.getClass().getName()).append("{\n");
		boolean first = true;
		for (Entry<?, ?> ent : map.entrySet()) {
			if (first) {
				first = false;
			} else {
				sb.append("\n");
			}
			sb.append("\t").append(ent.getKey()).append(" = ").append(ent.getValue());
		}
		sb.append("\n}");
		return sb.toString();
	}

	/**
	 * 将数组转换成字符串数组
	 * 
	 * @param objs
	 * @param ac
	 * @return
	 */
	public static String[] convert2StringArray(Object[] objs, ArrayConverter ac) {
		if (null == objs) {
			return null;
		}
		String[] strs = new String[objs.length];
		for (int i = 0; i < objs.length; i++) {
			strs[i] = ac.convert(objs[i]);
		}
		return strs;
	}

	/**
	 * 将集合转换成字符串数组
	 * 
	 * @param objs
	 * @param ac
	 * @return
	 */
	public static String[] convert2StringArray(Collection<?> objs, ArrayConverter ac) {
		if (null == objs) {
			return null;
		}
		String[] strs = new String[objs.size()];
		int i = 0;
		for (Object obj : objs) {
			strs[i++] = ac.convert(obj);
		}
		return strs;
	}

	/**
	 * 去掉前后的空字符,空串返回""
	 * 
	 * @param string
	 * @return
	 */
	public static String trim(String string) {
		if (isTrimEmpty(string)) {
			return "";
		}
		return string.trim();
	}

	public static String trimByChar(String string, char c) {
		if (isTrimEmpty(string)) {
			return "";
		}
		int start = 0;
		int end = string.length();
		for (; start < string.length(); start++) {
			if (string.charAt(start) != c) {
				break;
			}
		}
		for (; end > 0; end--) {
			if (string.charAt(end - 1) != c) {
				break;
			}
		}
		if (start > end) {
			return "";
		}
		return string.substring(start, end);
	}

	/**
	 * 判断所有对象的字符串是否均不为 null 和 ""
	 * 
	 * @param objs
	 * @return
	 */
	public static boolean allNotEmpty(Object[] objs) {
		for (Object str : objs) {
			if (isEmpty(toString(str)))
				return false;
		}
		return true;
	}

	/**
	 * 判断所有对象的字符串是否均不为 null 和 ""
	 * 
	 * @param objs
	 * @return
	 */
	public static boolean allNotEmpty(Collection<?> objs) {
		for (Object str : objs) {
			if (isEmpty(toString(str)))
				return false;
		}
		return true;
	}

	/**
	 * 判断所有对象的字符串是否均不为 null 和 空格字符串
	 * 
	 * @param strs
	 * @return
	 */
	public static boolean allNotTrimEmpty(Object[] strs) {
		for (Object str : strs) {
			if (isTrimEmpty(toString(str)))
				return false;
		}
		return true;
	}

	/**
	 * 判断所有对象的字符串是否均不为 null 和 空格字符串
	 * 
	 * @param objs
	 * @return
	 */
	public static boolean allNotTrimEmpty(Collection<?> strs) {
		for (Object str : strs) {
			if (isTrimEmpty(toString(str)))
				return false;
		}
		return true;
	}

	/**
	 * 获取字符串长度，包括中文（中文2字符）
	 * 
	 * @param value
	 * @return
	 */
	public static int lengthOfGBK(String value) {
		if (value == null)
			return 0;
		StringBuffer buff = new StringBuffer(value);
		int length = 0;
		String stmp;
		for (int i = 0; i < buff.length(); i++) {
			stmp = buff.substring(i, i + 1);
			try {
				stmp = new String(stmp.getBytes("utf8"));
			} catch (Exception e) {
			}
			if (stmp.getBytes().length > 1) {
				length += 2;
			} else {
				length += 1;
			}
		}
		return length;
	}

	/**
	 * 将数组中的字符串进行trim操作，不操作null对象
	 * 
	 * @param strs
	 */
	public static void trimArrayItems(String[] strs) {
		for (int i = 0; i < strs.length; i++) {
			if (null != strs[i]) {
				strs[i] = strs[i].trim();
			}
		}
	}

	public static interface ArrayConverter {
		public String convert(Object source);
	}

	public static String toGBKLength(String src, int destLen, char fill) {
		StringBuffer sb = new StringBuffer(src);
		int i = lengthOfGBK(sb.toString());
		if (i > destLen) {
			while (i > destLen - 3) {
				sb.delete(sb.length() - 1, sb.length());
				i = lengthOfGBK(sb.toString());
			}
			sb.append("...");
		}
		i = lengthOfGBK(sb.toString());
		while (i < destLen) {
			sb.append(fill);
			i = lengthOfGBK(sb.toString());
		}
		return sb.toString();
	}

	public static String toGBKLength(String src, int destLen) {
		return toGBKLength(src, destLen, ' ');
	}

	public static String toLength(String src, int destLen, char fill) {
		if (src.length() == destLen) {
			return src;
		} else if (src.length() > destLen) {
			src = src.substring(0, destLen - 3) + "...";
		} else {
			src = src + repeat(fill + "", destLen - src.length());
		}
		return src;
	}

	public static String toLength(String src, int destLen) {
		return toGBKLength(src, destLen, ' ');
	}

	public static boolean endBy(String str, String strShort) {
		return (str.lastIndexOf(strShort) == str.length() - 1);
	}

	public static boolean startBy(String str, String strShort) {
		return (str.indexOf(strShort) == 0);
	}

	public static String[] split(String src, String regex) {
		return toString(src).split(regex);
	}

	public static String[] splitByString(String src, String s) {
		if (StringUtil.isEmpty(src)) {
			return new String[] { "" };
		}
		StringBuffer sb = new StringBuffer(src);
		ArrayList<String> list = new ArrayList<String>();
		while (sb.length() > 0) {
			int pos = sb.indexOf(s);
			if (pos == -1) {
				list.add(sb.toString());
				break;
			} else if (pos == 0) {
				list.add("");
				sb.delete(0, pos + 1);
			} else {
				list.add(sb.substring(0, pos));
				sb.delete(0, pos + 1);
			}
		}
		return list.toArray(new String[] {});
	}

}
